package com.youbug.mall.product_pms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.youbug.common.vo.QueryVo;
import com.youbug.mall.product_pms.constant.ProductConstant;
import com.youbug.mall.product_pms.entity.*;
import com.youbug.mall.product_pms.mapper.AttrGroupMapper;
import com.youbug.mall.product_pms.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youbug.mall.product_pms.vo.Attr;
import com.youbug.mall.product_pms.vo.AttrGroupRelationVo;
import com.youbug.mall.product_pms.vo.SpuItemAttrGroupVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 属性分组 服务实现类
 * </p>
 *
 * @author youbug
 * @since 2023-07-08
 */
@Service
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupMapper, PmsAttrGroup> implements IAttrGroupService {

    @Autowired
    private IPmsAttrAttrgroupRelationService attrAttrgroupRelationService;
    @Autowired
    private IPmsAttrService attrService;
    @Autowired
    private IPmsProductAttrValueService productAttrValueService;
    @Autowired
    private ICategoryService categoryService;

    @Override
    public IPage<PmsAttrGroup> getAttrGroupPage(QueryVo<PmsAttrGroup> queryVo) {

        Page<PmsAttrGroup> paramPage = new Page<>();

        paramPage.setCurrent(queryVo.getCurrentPage());

        paramPage.setSize(queryVo.getPageSize());

        QueryWrapper<PmsAttrGroup> wrapper = new QueryWrapper<>();

        PmsAttrGroup attrGroup = queryVo.getPayload();

        if(!ObjectUtils.isEmpty(attrGroup)){
            if(!ObjectUtils.isEmpty(attrGroup.getCatalogId())) {
                wrapper.eq("catalog_id", attrGroup.getCatalogId());
            }
            if(!ObjectUtils.isEmpty(attrGroup.getAttrGroupName())) {
                wrapper.like("attr_group_name", attrGroup.getAttrGroupName());
            }
            if(!ObjectUtils.isEmpty(attrGroup.getDescript())) {
                wrapper.like("descript", attrGroup.getDescript());
            }
        }
        Page<PmsAttrGroup> page = this.page(paramPage, wrapper);
        List<PmsAttrGroup> records = page.getRecords();
        if(!CollectionUtils.isEmpty(records)){
            Set<Long> idSet = records.stream().map(e -> {
                return e.getCatalogId();
            }).collect(Collectors.toSet());

            List<PmsCategory> categories = categoryService.listByIds(idSet);
            Map<Long, String> nameMap = categories.stream().collect(Collectors.toMap(PmsCategory::getCatId, PmsCategory::getName, (v, v1) -> v));

            records.forEach(e->{
                e.setCatalogNameTemp(nameMap.get(e.getCatalogId()));
            });
        }
        return page;
    }

    @Override
    public List<PmsAttr> getRelationAttr(QueryVo<Long> queryVo) {

        QueryWrapper<PmsAttrAttrgroupRelation> wrapper = new QueryWrapper<>();

        Long attrGroupId = queryVo.getPayload();

        if(!ObjectUtils.isEmpty(attrGroupId)){
            wrapper.select("attr_id").eq("attr_group_id", attrGroupId);
            List<PmsAttrAttrgroupRelation> relations = attrAttrgroupRelationService.list(wrapper);
            List<Long> attrIds = relations.stream().map(PmsAttrAttrgroupRelation::getAttrId).collect(Collectors.toList());
            List<PmsAttr> attrs = null;
            if(!CollectionUtils.isEmpty(attrIds)){
                attrs = attrService.listByIds(attrIds);
            }
            return attrs;
        }
        return null;
    }

    @Override
    @Transactional(transactionManager = "transactionManagerPms", rollbackFor = Exception.class)
    public Boolean deleteRelation(List<AttrGroupRelationVo> relationVos) {
        QueryWrapper<PmsAttrAttrgroupRelation> wrapper = new QueryWrapper<>();
        for (int i = 0; i < relationVos.size(); i++) {
            AttrGroupRelationVo vo = relationVos.get(i);
            wrapper.and(e->{e.eq("attr_id", vo.getAttrId()).eq("attr_group_id", vo.getAttrGroupId());});
            if(i < relationVos.size()){
                wrapper.or();
            }
        }
        boolean remove = attrAttrgroupRelationService.remove(wrapper);
        return remove;
    }

    @Override
    public IPage<PmsAttr> getNoAttRelation(QueryVo<PmsAttr> queryVo) {
        Page<PmsAttr> paramPage = new Page<>();

        paramPage.setCurrent(queryVo.getCurrentPage());

        paramPage.setSize(queryVo.getPageSize());

        PmsAttr attr = queryVo.getPayload();

        PmsAttrGroup attrGroup = this.getById(attr.getAttrGroupId());

        Long catalogId = attrGroup.getCatalogId();

        List<PmsAttrGroup> attrGroups = this.list(new QueryWrapper<PmsAttrGroup>().eq("catalog_id", catalogId));// 该分类下的所有分组

        List<Long> attrGroupIds = attrGroups.stream().map(PmsAttrGroup::getAttrGroupId).collect(Collectors.toList());

        if(!CollectionUtils.isEmpty(attrGroupIds)){
            List<PmsAttrAttrgroupRelation> relations = attrAttrgroupRelationService
                    .list(new QueryWrapper<PmsAttrAttrgroupRelation>().in("attr_group_id", attrGroupIds));

            List<Long> relationedAttrIds = relations.stream().map(PmsAttrAttrgroupRelation::getAttrId).collect(Collectors.toList());

            QueryWrapper<PmsAttr> wrapper = new QueryWrapper<>();

            wrapper.eq("catalog_id", catalogId).eq("attr_type", ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());

            Page<PmsAttr> attrs;

            if(!CollectionUtils.isEmpty(relationedAttrIds)){// 该分类下的所有分组关联的所有属性

                wrapper.notIn("attr_id", relationedAttrIds);

                attrs = attrService.page(paramPage, wrapper);
            }else{
                attrs = attrService.page(paramPage, wrapper);
            }
            return attrs;
        }
        return null;
    }

    @Override
    public List<PmsAttrGroup> getAttrGroupWithAttrByCatalogId(Long catalogId) {

        List<PmsAttrGroup> attrGroups = this.list(new QueryWrapper<PmsAttrGroup>().eq("catalog_id", catalogId));

        attrGroups.forEach(e->{

            e.setAttrs(attrService.getRelationAttrs(e.getAttrGroupId()));

        });
        return attrGroups;
    }

    @Override
    @Transactional(transactionManager = "transactionManagerPms", rollbackFor = Exception.class)
    public Boolean addRelations(List<AttrGroupRelationVo> relationVos) {
        if(CollectionUtils.isEmpty(relationVos)){
            return true;
        }
        List<PmsAttrAttrgroupRelation> relationList = relationVos.stream().map(e -> {
            PmsAttrAttrgroupRelation relation = new PmsAttrAttrgroupRelation();

            relation.setAttrId(e.getAttrId());
            relation.setAttrGroupId(e.getAttrGroupId());
            return relation;
        }).collect(Collectors.toList());

        attrAttrgroupRelationService.saveBatch(relationList);

        return true;
    }

    @Override
    public List<SpuItemAttrGroupVo> getAttrGroupWithAttrsBySpuId(Long spuId,Long catalogId) {

        List<SpuItemAttrGroupVo> vos = new ArrayList<>();
        // 查出当前spu对应的所有属性的分组信息以及当前分组下的所有属性对应的值
        List<PmsAttrGroup> attrGroups = this.list(new QueryWrapper<PmsAttrGroup>().eq("catalog_id", catalogId));

        List<Long> attrGroupIds = attrGroups.stream().map(PmsAttrGroup::getAttrGroupId).collect(Collectors.toList());

        List<PmsAttrAttrgroupRelation> attrgroupRelations = attrAttrgroupRelationService
                .list(new QueryWrapper<PmsAttrAttrgroupRelation>().in("attr_group_id", attrGroupIds));

        Map<Long, Long> relationMap = attrgroupRelations.stream()
                .collect(Collectors.toMap(PmsAttrAttrgroupRelation::getAttrId, PmsAttrAttrgroupRelation::getAttrGroupId, (v, v1) -> v1));

        List<PmsProductAttrValue> productAttrValues = productAttrValueService.list(new QueryWrapper<PmsProductAttrValue>().eq("spu_id", spuId));

        Map<Long, List<Attr>> attrsGroupMap = new HashMap<>();

        for (PmsProductAttrValue attrValue : productAttrValues) {

            Long attrGroupId = relationMap.get(attrValue.getAttrId());

            List<Attr> list = attrsGroupMap.get(attrGroupId);

            Attr attr = new Attr();
            attr.setAttrId(attrValue.getAttrId());
            attr.setAttrName(attrValue.getAttrName());
            attr.setAttrValue(attrValue.getAttrValue());

            if(list==null){
                list = new ArrayList<>();
                list.add(attr);

                attrsGroupMap.put(attrGroupId, list);
            }else{
                list.add(attr);
            }
        }
        for (PmsAttrGroup attrGroup : attrGroups) {
            SpuItemAttrGroupVo item = new SpuItemAttrGroupVo();
            item.setGroupName(attrGroup.getAttrGroupName());
            item.setAttrs(attrsGroupMap.get(attrGroup.getAttrGroupId()));

            vos.add(item);
        }
        return vos;
    }


}
